import httpx
import json
import time
import logging
import uuid
import cloudscraper
from typing import Dict, Any, AsyncGenerator

from fastapi import HTTPException
from fastapi.responses import StreamingResponse, JSONResponse

from app.core.config import settings
from app.providers.base_provider import BaseProvider
from app.utils.sse_utils import create_sse_data, create_chat_completion_chunk, DONE_CHUNK

logger = logging.getLogger(__name__)

class InceptionAIProvider(BaseProvider):
    def __init__(self):
        # 使用 cloudscraper 创建一个 session 对象
        self.scraper = cloudscraper.create_scraper()
        self.chats_new_url = "https://chat.inceptionlabs.ai/api/v1/chats/new"
        self.completions_url = "https://chat.inceptionlabs.ai/api/chat/completions"

    async def chat_completion(self, request_data: Dict[str, Any]) -> StreamingResponse:
        
        async def stream_generator() -> AsyncGenerator[bytes, None]:
            request_id = f"chatcmpl-{uuid.uuid4()}"
            try:
                # cloudscraper 不支持异步，所以我们在异步函数中以同步方式调用它
                # 对于 I/O 密集型操作，这在 FastAPI 中是可接受的
                chat_id = self._get_new_chat_id()
                
                payload = self._prepare_payload(request_data, chat_id)
                headers = self._prepare_headers()

                # 使用 scraper 发送流式请求
                response = self.scraper.post(self.completions_url, headers=headers, json=payload, stream=True)
                response.raise_for_status()

                for line in response.iter_lines():
                    if line.startswith(b"data:"):
                        content = line[len(b"data:"):].strip()
                        if content == b"[DONE]":
                            break
                        try:
                            data = json.loads(content)
                            delta_content = data.get("choices", [{}])[0].get("delta", {}).get("content")
                            if delta_content is not None:
                                chunk = create_chat_completion_chunk(request_id, settings.DEFAULT_MODEL, delta_content)
                                yield create_sse_data(chunk)
                        except json.JSONDecodeError:
                            logger.warning(f"无法解析 SSE 数据块: {content}")
                            continue
                
                final_chunk = create_chat_completion_chunk(request_id, settings.DEFAULT_MODEL, "", "stop")
                yield create_sse_data(final_chunk)
                yield DONE_CHUNK

            except Exception as e:
                logger.error(f"处理流时发生错误: {e}", exc_info=True)
                error_message = f"内部错误: {str(e)}"
                error_chunk = create_chat_completion_chunk(request_id, settings.DEFAULT_MODEL, error_message, "stop")
                yield create_sse_data(error_chunk)
                yield DONE_CHUNK

        return StreamingResponse(stream_generator(), media_type="text/event-stream")

    def _get_new_chat_id(self) -> str:
        headers = self._prepare_headers()
        payload = {
            "chat": {
                "id": "", "title": "新对话", "models": ["mercury"], "params": {},
                "history": {"messages": {}, "currentId": None},
                "messages": [], "tags": [], "timestamp": int(time.time() * 1000)
            }
        }
        try:
            # 使用 scraper 发送请求，它会自动处理 Cloudflare
            response = self.scraper.post(self.chats_new_url, headers=headers, json=payload)
            response.raise_for_status()
            data = response.json()
            chat_id = data.get("id")
            if not chat_id:
                raise ValueError("'/chats/new' 响应中缺少 'id' 字段。")
            logger.info(f"成功获取新的 chat_id: {chat_id}")
            return chat_id
        except Exception as e:
            logger.error(f"获取 new_chat_id 失败: {e}", exc_info=True)
            raise HTTPException(status_code=500, detail="无法创建新的上游聊天会话。")

    def _prepare_headers(self) -> Dict[str, str]:
        # cloudscraper 会自动管理 User-Agent 和 Cookie，我们只需提供必要的其他头信息
        return {
            "Accept": "*/*",
            "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
            "Authorization": "Bearer",
            "Content-Type": "application/json",
            "Origin": "https://chat.inceptionlabs.ai",
            "Referer": "https://chat.inceptionlabs.ai/",
        }

    def _prepare_payload(self, request_data: Dict[str, Any], chat_id: str) -> Dict[str, Any]:
        messages = request_data.get("messages", [])
        return {
            "stream": True,
            "model": request_data.get("model", settings.DEFAULT_MODEL),
            "messages": messages,
            "session_id": str(uuid.uuid4()),
            "chat_id": chat_id,
            "id": str(uuid.uuid4())
        }

    async def get_models(self) -> JSONResponse:
        model_data = {
            "object": "list",
            "data": [
                {"id": name, "object": "model", "created": int(time.time()), "owned_by": "lzA6"}
                for name in settings.KNOWN_MODELS
            ]
        }
        return JSONResponse(content=model_data)
